﻿using System;
using System.Linq;
using OblivionLevelingHelper.Birthsigns;
using OblivionLevelingHelper.Classes;
using OblivionLevelingHelper.Races;
using OblivionLevelingHelper.Skills;
using OblivionLevelingHelper.Attributes;

namespace OblivionLevelingHelper
{
    public class Character
    {
        public Gender Gender { get; private set; }
        public Race Race { get; private set; }
        public Birthsign Birthsign { get; private set; }
        public Class Class { get; private set; }
        public SkillSet SkillSet { get; private set; }
        public AttributeSet AttributeSet { get; private set; }
        
        public Character()
        {
            // Configure default test character
            Gender = Gender.Male;
            Race = new Nord();
            Birthsign = new Lady();
            Class = new Barbarian();
            SkillSet = new SkillSet(this);
            AttributeSet = new AttributeSet(this);

            // Setup Attribute-Skill relations
            SetupStatRelations();

            // Output test
            Print();
        }

        public void SetupStatRelations()
        {
            // Strength
            var attrStr = AttributeSet.GetAttribute(AttributeTypes.Strength);
            attrStr.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Blade));
            attrStr.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Blunt));
            attrStr.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.HandToHand));

            // Intelligence
            var attrInt = AttributeSet.GetAttribute(AttributeTypes.Intelligence);
            attrInt.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Alchemy));
            attrInt.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Conjuration));
            attrInt.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Mysticism));

            // Willpower
            var attrWill = AttributeSet.GetAttribute(AttributeTypes.Willpower);
            attrWill.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Alteration));
            attrWill.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Destruction));
            attrWill.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Restoration));

            // Agility
            var attrAgi = AttributeSet.GetAttribute(AttributeTypes.Agility);
            attrAgi.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Marksmanship));
            attrAgi.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Security));
            attrAgi.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Sneak));

            // Speed
            var attrSpd = AttributeSet.GetAttribute(AttributeTypes.Speed);
            attrSpd.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Acrobatics));
            attrSpd.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Athletics));
            attrSpd.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.LightArmor));

            // Endurance
            var attrEnd = AttributeSet.GetAttribute(AttributeTypes.Endurance);
            attrEnd.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Armorer));
            attrEnd.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Block));
            attrEnd.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.HeavyArmor));

            // Personality
            var attrPers = AttributeSet.GetAttribute(AttributeTypes.Personality);
            attrPers.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Illusion));
            attrPers.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Mercantile));
            attrPers.AddGoverningSkill(SkillSet.GetSkill(SkillTypes.Speechcraft));
        }

        public void Print()
        {
            Console.WriteLine("---General information---");
            Console.WriteLine("Gender: " + Gender);
            Console.WriteLine("Race: " + Race.Name);

            Console.WriteLine("\n---Birthsign---");
            Console.WriteLine("Name: " + Birthsign.Name);
            Console.WriteLine("Description: " + Birthsign.Effect);

            Console.WriteLine("\n---Class---");
            Console.WriteLine("Name: " + Class.Name);
            Console.WriteLine("Specialization: " + Class.Specialization.Name);
            Console.WriteLine("Favored Attributes: " + Class.FavoredAttributeOne + " and " + Class.FavoredAttributeTwo);

            // Display major Skills
            var skillTypes = "";
            var majorSkills = Class.GetMajorSkillTypes().OrderBy(ms => ms.ToString());
            for (var i = 0; i < majorSkills.Count(); i++)
            {
                var currentSkillType = majorSkills.ElementAt(i);
                skillTypes += i == 0 ? currentSkillType.ToString() : ", " + currentSkillType;
            }
            Console.WriteLine("Major Skills: " + skillTypes + "\n");

            // Display all Attributes
            var attributes = "";
            foreach (var attr in AttributeSet.GetAttributes())
            {
                attributes += attr.GetName() + ": " + attr.CalculateStat() + "\n";
            }
            Console.WriteLine("---Attributes---\n" + attributes);

            // Display all Skills
            var skills = "";
            foreach (var skill in SkillSet.GetSkills())
            {
                skills += skill.GetName() + ": " + skill.CalculateStat() + (skill.IsMajor() ? " (Major)" : "") + "\n";
            }
            Console.WriteLine("---Skills---\n" + skills);
        }
    }

    public enum Gender
    {
        Male,
        Female
    }
}
